package com.innoking.docsys.workflow.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.innoking.docsys.utils.JsonToOtherUtil;
import com.innoking.docsys.utils.OtherPojo;
import com.innoking.docsys.utils.ResultObjVO;
import com.innoking.docsys.utils.ResultUtil;
import com.innoking.docsys.workflow.dto.UpmsActDefine;
import com.innoking.docsys.workflow.module.WorkflowModelVO;
import com.innoking.docsys.workflow.service.WorkflowDefineService;
import com.innoking.docsys.workflow.service.WorkflowModelService;
import com.innoking.docsys.workflow.utils.WorkflowPageUtil;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述:
 *
 * @author zyp
 * @description 工作流模型servcice实现类
 * @create 2019-09-06 14:17
 */
@Service
public class WorkflowModelServiceImpl implements WorkflowModelService {

    Logger logger= LoggerFactory.getLogger(WorkflowModelServiceImpl.class);

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    public WorkflowDefineService workflowDefineService;

    @Override
    public ResultObjVO getActModel(WorkflowModelVO workflowModel) {
        int offset = 1;
        int limit = 1;
        String search = workflowModel.getParameter1();
        Map<String, Object> result = new HashMap<>(2);
        List<Model> rows = repositoryService.createModelQuery().list();
        List<Model>  finalList = WorkflowPageUtil.pagingActModel(rows,offset,limit,search);
        result.put("rows",finalList);
        result.put("total",rows.size());
        return ResultUtil.success(result);
    }

    /**
     * @author:zyp
     * @description 创建工作流用户
     * @date: 2019/9/6 14:29
     * @return 
     */
    @Override
    public ResultObjVO createModel(WorkflowModelVO workflowModel) {
        String name = workflowModel.getName();
        String key = workflowModel.getKey();
        String description = workflowModel.getDescription();
        try {
            List<Model> list = repositoryService.createModelQuery().list();
            for(Model model : list){
                String key1 = model.getKey();
                if(key.equals(key1)){
                    return ResultUtil.error("key值不能重复");
                }
            }
            ObjectMapper objectMapper = new ObjectMapper();
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.set("stencilset", stencilSetNode);
            Model modelData = repositoryService.newModel();
            ObjectNode modelObjectNode = objectMapper.createObjectNode();
            modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
            description = StringUtils.defaultString(description);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
            modelData.setMetaInfo(modelObjectNode.toString());
            modelData.setName(name);
            modelData.setKey(StringUtils.defaultString(key));
            repositoryService.saveModel(modelData);
            repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
            return  ResultUtil.resData(modelData.getId(),"保存成功","200");
        } catch (Exception e) {
            logger.error("创建模型失败：", e);
            return  null;
        }
    }

    /**
     * @author:zyp
     * @description 删除工作流模型
     * @date: 2019/9/6 15:06
     * @return
     */
    @Override
    public ResultObjVO delModel(String ids) {
        if (StringUtils.isBlank(ids)) {
            return ResultUtil.error("无可删除模型");
        }else{
            String[] idArray = ids.split("-");
            for (String idStr : idArray) {
                if (StringUtils.isBlank(idStr)) {
                    continue;
                }
                repositoryService.deleteModel(idStr);
            }
        }
        return ResultUtil.success("删除成功");
    }

    /**
     * @author:zyp
     * @description 部署模型 同时定义流程
     * @date: 2019/9/6 15:41
     * @return 
     */
    @Override
    public ResultObjVO deployModel(WorkflowModelVO workflowModel) {
        //id[0]:模型id;id[1]:定义的code
        String modelId = workflowModel.getModelId();
        String defineCode = workflowModel.getDefineCode();
        Model modelData = repositoryService.getModel(modelId);
        ObjectNode modelNode = null;
        try {
            /*****************部署流程*************/
            modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
            byte[] bpmnBytes = null;
            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            bpmnBytes = new BpmnXMLConverter().convertToXML(model);
            String processName = modelData.getName() + ".bpmn20.xml";
            Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8")).deploy();
            /*****************部署流程*************/
            /*****************定义流程*************/
            //模型key
            String key = modelData.getKey();
            //默认更换定义
            workflowDefineService.updateStatusByAdCode(key);
            UpmsActDefine actDefine = new UpmsActDefine();
            actDefine.setAdKey(key);
            actDefine.setAdStatus(1L);
            actDefine.setCreateTime(new Date());
            actDefine.setAdCode(defineCode);
            workflowDefineService.insert(actDefine);
            /*****************定义流程*************/
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("根据模型部署流程失败：modelId={}", modelId, e);
        }
        return ResultUtil.success("部署成功");
    }


}